﻿using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Web.Mvc.Html;
using System.Text;
using MvcContrib.FluentHtml.Elements;
using MvcContrib.FluentHtml.Expressions;
using ProjetoComperio.Framework.Web.Security;

namespace ProjetoComperio.Presentation.Web.GlobalResources.HtmlHelper
{

    public static class HtmlHelperExtension
    {
        #region TextField
        /// <summary>
        ///  This method renders a textField that should be used in Strongly typed views
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="view"></param>
        /// <param name="expression"></param>
        /// <param name="labelValue"></param>
        /// <returns></returns>
        public static string TextField<T>(this MvcContrib.FluentHtml.IViewModelContainer<T> view, Expression<Func<T, object>> expression, String labelValue) where T : class
        {
            return TextField(view, expression, labelValue, String.Empty);
        }

        /// <summary>
        ///  This method renders a textField that should be used in Strongly typed views
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="view"></param>
        /// <param name="expression"></param>
        /// <param name="labelValue"></param>
        /// <param name="fieldValue"></param>
        /// <returns></returns>
        public static string TextField<T>(this MvcContrib.FluentHtml.IViewModelContainer<T> view, Expression<Func<T, object>> expression, String labelValue, String fieldValue) where T : class
        {
            return TextField(view, expression, labelValue, "TextBox", String.Empty);
        }

        /// <summary>
        /// This method renders a textField(with custom date format) that should be used in Strongly typed views
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="view"></param>
        /// <param name="expression"></param>
        /// <param name="cssStyle"></param>
        /// <param name="labelValue"></param>
        /// <returns></returns>
        public static string DateField<T>(this MvcContrib.FluentHtml.IViewModelContainer<T> view, Expression<Func<T, object>> expression, string cssStyle, String labelValue) where T : class
        {
            return TextField(view, expression, labelValue, cssStyle, String.Empty);
        }

        /// <summary>
        ///  This method renders a textField(with date format) that should be used in Strongly typed views
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="view"></param>
        /// <param name="expression"></param>
        /// <param name="labelValue"></param>
        /// <returns></returns>
        public static string DateField<T>(this MvcContrib.FluentHtml.IViewModelContainer<T> view, Expression<Func<T, object>> expression, String labelValue) where T : class
        {
            return TextField(view, expression, labelValue, "TextBoxDate", String.Empty);
        }




        #region Support
        /// <summary>
        /// Generic method that renders a textfield with CSS class
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="view"></param>
        /// <param name="expression"></param>
        /// <param name="labelValue"></param>
        /// <param name="cssClass"></param>
        /// <returns></returns>
        private static string TextField<T>(this MvcContrib.FluentHtml.IViewModelContainer<T> view, Expression<Func<T, object>> expression, String labelValue, string cssClass, String fieldValue) where T : class
        {
            var textBoxName = expression.GetNameFor(view);
            var htmlControl = new StringBuilder();
            htmlControl.Append(Label(view.Html, textBoxName, labelValue));
            htmlControl.Append("<div class='div_texbox'>");
            htmlControl.Append(new TextBox(expression.GetNameFor(view), expression.GetMemberExpression(), null).Value(BindHtmlHelperValue(view, expression)).Class(cssClass).ToString());

            htmlControl.Append("</div>");
            return htmlControl.ToString();
        }

        /// <summary>
        /// This method renders a span tag
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public static String SpanMessage(String name)
        {

            return "<span id='" + name + "Message' name='" + name +
                   "Message'></span>";
        }

        /// <summary>
        /// This method binds an value inside model data
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="view"></param>
        /// <param name="expression"></param>
        /// <returns></returns>
        public static string BindHtmlHelperValue<T>(MvcContrib.FluentHtml.IViewModelContainer<T> view, Expression<Func<T, object>> expression) where T : class
        {
            if (view.ViewModel == null || expression.GetValueFrom(view.ViewModel) == null)
                return String.Empty;

            return expression.GetValueFrom(view.ViewModel).ToString();
        }
        #endregion

        #endregion

        #region Label

        /// <summary>
        /// This method creates a label
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string Label(this System.Web.Mvc.HtmlHelper htmlHelper, String controlToReference, String value)
        {
            return "<label for='" + controlToReference + "'  class='TextBoxLabel2'>" + value + "</label>";
        }

        #endregion

        #region PasswordField
        public static string PasswordField<T>(this MvcContrib.FluentHtml.IViewModelContainer<T> view, Expression<Func<T, object>> expression, String labelValue) where T : class
        {
            var textBoxName = expression.GetNameFor(view);
            var htmlControl = new StringBuilder();
            htmlControl.Append(Label(view.Html, textBoxName, labelValue));
            htmlControl.Append("<div class='div_texbox'>");
            htmlControl.Append(new MvcContrib.FluentHtml.Elements.Password(expression.GetNameFor(view), expression.GetMemberExpression(), null).Value(expression.GetValueFrom(view.ViewModel)).Class("TextBox").ToString());
            htmlControl.Append(SpanMessage(textBoxName));
            htmlControl.Append("</div>");

            return htmlControl.ToString();
        }

        #endregion

        #region TextArea

        /// <summary>
        /// This method renders a textArea
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="view"></param>
        /// <param name="expression"></param>
        /// <param name="labelValue"></param>
        /// <returns></returns>
        public static string TextArea<T>(this MvcContrib.FluentHtml.IViewModelContainer<T> view, Expression<Func<T, object>> expression, String labelValue) where T : class
        {
            var textAreaName = expression.GetNameFor(view);
            var htmlControl = new StringBuilder();
            htmlControl.Append(Label(view.Html, textAreaName, labelValue));
            htmlControl.Append("<div class='div_texboxArea'>");
            htmlControl.Append(new MvcContrib.FluentHtml.Elements.TextArea(expression.GetNameFor(view), expression.GetMemberExpression(), null).Value(expression.GetValueFrom(view.ViewModel)).Class("TextBoxArea").ToString());
            htmlControl.Append("<span id='" + expression.GetNameFor(view) + "Message' name='" + expression.GetNameFor(view) +
                           "Message'></span>");
            htmlControl.Append("</div>");

            return htmlControl.ToString();
        }

        #endregion

        #region RadioButtonList
        public static String RadioButtonList(this System.Web.Mvc.HtmlHelper htmlHelper, String fieldName, String labelValue, List<RadioButtonItem> values)
        {
            System.Text.StringBuilder html = new StringBuilder();
            foreach (var item in values)
                html.Append(item.Text + htmlHelper.RadioButton(fieldName, item.Value));

            return (Label(htmlHelper, fieldName, labelValue) + html.ToString());
        }
        #endregion

        #region  buttons

        public static string CommandField<T>(this MvcContrib.FluentHtml.IViewModelContainer<T> view, bool enableSubmitButton, string codeForReturnButton) where T : class
        {
            StringBuilder htmlButtons = new StringBuilder();

            htmlButtons.Append("<div align='right'>");
            htmlButtons.Append(RenderSubmit(enableSubmitButton));
            htmlButtons.Append(RenderReturnButton(codeForReturnButton));
            htmlButtons.Append("</div>");

            return htmlButtons.ToString();
        }

        #region Private Methods
        private static string RenderSubmit(bool enableSubmitButton)
        {
            if (enableSubmitButton)
                return "<input type='submit' id='Save' class='Button' value='Salvar' />";
            else
                return "<input type='submit' id='Save' class='Button' value='Salvar' disabled='disabled' />";

        }

        private static string RenderReturnButton(string codeForReturnButton)
        {
            return "<input type='button' id='Return' onclick=" + codeForReturnButton + " class='Button' value='Voltar' />";
        }
        #endregion

        #endregion

        #region ActionLink
        /// <summary>
        /// This method renders a link action if user has permission otherwise returns simple text
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="linkText"></param>
        /// <param name="controllerName"></param>
        /// <param name="actionName"></param>
        /// <param name="identity"></param>
        /// <returns></returns>
        public static String ActionLink(this System.Web.Mvc.HtmlHelper htmlHelper, string linkText, string controllerName, string actionName, System.Security.Principal.IIdentity identity)
        {
            ComperioMemberShipProvider provider = new ComperioMemberShipProvider();
            return (provider.UserHasPermission(controllerName, actionName, identity.Name) ? htmlHelper.ActionLink(linkText, actionName, controllerName).ToHtmlString() : Text(linkText));

        }
        private static String Text(String value)
        {

            return "<label>" + value + "</label>";
        }

        /// <summary>
        /// This method returns a validation icon 
        /// with a error message as tooltip
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static string ValidationImage(this System.Web.Mvc.HtmlHelper helper, string name)
        {
            if (helper.ViewData.ModelState[name] == null || helper.ViewData.ModelState[name].Errors.Count == 0)
                return String.Empty;

            var tagSpan = "<span class='errorImage' title='" + helper.ViewData.ModelState[name].Errors[0].ErrorMessage + "' > &nbsp;&nbsp; </span>";

            return tagSpan;
        }


        #endregion
    }


}
